﻿using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;

namespace ICodeShare.UI.Controls
{
    public class SelectionAdapter
    {
        #region "Fields"

        private Selector _selectorControl;

        #endregion "Fields"

        #region "Constructors"

        public SelectionAdapter(Selector selector)
        {
            SelectorControl = selector;
            SelectorControl.PreviewMouseUp += OnSelectorMouseDown;
        }

        #endregion "Constructors"

        #region "Events"

        public delegate void CancelEventHandler();

        public delegate void CommitEventHandler();

        public delegate void SelectionChangedEventHandler();

        public event CancelEventHandler Cancel;

        public event CommitEventHandler Commit;

        public event SelectionChangedEventHandler SelectionChanged;

        #endregion "Events"

        #region "Properties"

        public Selector SelectorControl
        {
            get { return _selectorControl; }
            set { _selectorControl = value; }
        }

        #endregion "Properties"

        #region "Methods"

        public void HandleKeyDown(KeyEventArgs key)
        {
            Debug.WriteLine(key.Key);
            switch (key.Key)
            {
                case Key.Down:
                    IncrementSelection();
                    break;

                case Key.Up:
                    DecrementSelection();
                    break;

                case Key.Enter:
                    if (Commit != null)
                    {
                        Commit();
                    }

                    break;

                case Key.Escape:
                    if (Cancel != null)
                    {
                        Cancel();
                    }

                    break;

                case Key.Tab:
                    if (Commit != null)
                    {
                        Commit();
                    }

                    break;
            }
        }

        private void DecrementSelection()
        {
            if (SelectorControl.SelectedIndex == -1)
            {
                SelectorControl.SelectedIndex = SelectorControl.Items.Count - 1;
            }
            else
            {
                SelectorControl.SelectedIndex -= 1;
            }
            if (SelectionChanged != null)
            {
                SelectionChanged();
            }
        }

        private void IncrementSelection()
        {
            if (SelectorControl.SelectedIndex == SelectorControl.Items.Count - 1)
            {
                SelectorControl.SelectedIndex = -1;
            }
            else
            {
                SelectorControl.SelectedIndex += 1;
            }
            if (SelectionChanged != null)
            {
                SelectionChanged();
            }
        }

        private void OnSelectorMouseDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                Point position = e.GetPosition(_selectorControl);
                HitTestResult result = VisualTreeHelper.HitTest(_selectorControl, position);
                if (result == null) return;
                ListBoxItem item = GetParentObject<ListBoxItem>(result.VisualHit);
                if (item != null)
                {
                    item.IsSelected = true;
                    if (Commit != null)
                    {
                        Commit();
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;

            }
        }

        public static T GetParentObject<T>(DependencyObject obj, string name = "") where T : FrameworkElement
        {
            DependencyObject parent = VisualTreeHelper.GetParent(obj);

            while (parent != null)
            {
                if (parent is T && (((T)parent).Name == name | string.IsNullOrEmpty(name)))
                {
                    return (T)parent;
                }
                parent = VisualTreeHelper.GetParent(parent);
            }
            return null;
        }
        #endregion "Methods"
    }
}